#!/usr/bin/python
# -*- coding: UTF-8 -*-
import rospy
import RPi.GPIO as GPIO
import time

#微秒级计时
def delayMicrosecond(t):    # 微秒级延时函数
    start,end=0,0           # 声明变量
    start=time.time()       # 记录开始时间
    t=(t-3)/1000000     # 将输入t的单位转换为秒，-3是时间补偿
    while end-start<t:  # 循环至时间差值大于或等于设定值时
        end=time.time()     # 记录结束时间

#获得元组数据：温度、湿度
def get_temp_humid(data):

    humidity_bit = data[0:8]		#分组
    humidity_point_bit = data[8:16]
    temperature_bit = data[16:24]
    temperature_point_bit = data[24:32]
    check_bit = data[32:40]

    humidity = 0
    humidity_point = 0
    temperature = 0
    temperature_point = 0
    check = 0

    for i in range(8):
        humidity += humidity_bit[i] * 2 ** (7 - i)				#转换成十进制数据
        humidity_point += humidity_point_bit[i] * 2 ** (7 - i)
        temperature += temperature_bit[i] * 2 ** (7 - i)
        temperature_point += temperature_point_bit[i] * 2 ** (7 - i)
        check += check_bit[i] * 2 ** (7 - i)

    tmp = humidity + humidity_point + temperature + temperature_point		#十进制的数据相加
    if check == tmp:								#数据校验，相等则输出
        # print("temprature:{}\thumidity:{}".format(temperature,humidity))
        return temperature, humidity
    else:	#错误输出错误信息，和校验数据
        pass
        # print ("temprature:{}\thumidity:{}\tcheck:{}\ttmp:{}".format(temperature,humidity,check,tmp))


def GPIO_DHT11_init(channel):
    GPIO.setmode(GPIO.BCM)		#以BCM编码格式
    time.sleep(1)			#时延一秒



#获得二进制数据data
def get_DHT11(channel):
    data = []

    GPIO.setup(channel, GPIO.OUT)
    
    GPIO.output(channel, GPIO.LOW)
    delayMicrosecond(20*1000)		#给信号提示传感器开始工作
    GPIO.output(channel, GPIO.HIGH)
    delayMicrosecond(20)
    

    GPIO.setup(channel, GPIO.IN)
    
    a=time.time()           # 记录循环开始时间
    while GPIO.input(channel): # 一直循环至输入为低电平
        b=time.time()       # 记录结束时间
        if (b-a)>0.1:       # 判断循环时间是否超过0.1秒，避免程序进入死循环卡死
            return           

    a=time.time()
    while GPIO.input(channel)==0:  # 一直循环至输入为高电平
        b=time.time()
        if (b-a)>0.1:
            return

    a=time.time()
    while GPIO.input(channel): # 一直循环至输入为低电平
        b=time.time()
        if (b-a)>=0.1:
            return
    
    #读取40位数据
    j = 0				#计数器
    while j < 40:
        k = 0
        while GPIO.input(channel) == GPIO.LOW:
            continue

        while GPIO.input(channel) == GPIO.HIGH:
            k += 1
            if k > 100:
                break

        if k < 8:
            data.append(0)
        else:
            data.append(1)

        j += 1

    
    # print(data)				#输出初始数据高低电平
    return data



if __name__ == "__main__":
    # print("start...")
    rospy.set_param("temprature",27)
    rospy.set_param("humidity",55)    
    channel = 26			#引脚号4
    #1.GPIO初始化
    GPIO_DHT11_init(channel)
    while True:
        #2.获取DHT11传感器二进制数据
        data = get_DHT11(channel)
        #3.获得温度、湿度
        try:
            temp,humid = get_temp_humid(data)
        except TypeError:
            time.sleep(0.5)
            continue
        print("temprature:{}\thumidity:{}".format(temp,humid))
        rospy.set_param("temprature",temp)
        rospy.set_param("humidity",humid)
        time.sleep(0.5)
